<template>
	<view class="u-form">
		<slot />
	</view>
</template>

<script>
	/**
	 * form 表单
	 * @description 此组件一般用于表单场景，可以配置Input输入框，Select弹出框，进行表单验证等。
	 * @tutorial http://uviewui.com/components/form.html
	 * @property {Object} model 表单数据对象
	 * @property {Boolean} border-bottom 是否显示表单域的下划线边框
	 * @property {String} label-position 表单域提示文字的位置，left-左侧，top-上方
	 * @property {String Number} label-width 提示文字的宽度，单位rpx（默认90）
	 * @property {Object} label-style lable的样式，对象形式
	 * @property {String} label-align lable的对齐方式
	 * @property {Object} rules 通过ref设置，见官网说明
	 * @property {Array} error-type 错误的提示方式，数组形式，见上方说明(默认['message'])
	 * @example <u-form :model="form" ref="uForm"></u-form>
	 */

	export default {
		name: 'u-form',
		props: {
			// 当前form的需要验证字段的集合
			model: {
				type: Object,
				default () {
					return {};
				}
			},
			// 验证规则
			// rules: {
			// 	type: [Object, Function, Array],
			// 	default() {
			// 		return {};
			// 	}
			// },
			// 有错误时的提示方式，message-提示信息，border-如果input设置了边框，变成呈红色，
			// border-bottom-下边框呈现红色，none-无提示
			errorType: {
				type: Array,
				default () {
					return ['message', 'toast']
				}
			},
			// 是否显示表单域的下划线边框
			borderBottom: {
				type: Boolean,
				default: true
			},
			// label的位置，left-左边，top-上边
			labelPosition: {
				type: String,
				default: 'left'
			},
			// label的宽度，单位rpx
			labelWidth: {
				type: [String, Number],
				default: 90
			},
			// lable字体的对齐方式
			labelAlign: {
				type: String,
				default: 'left'
			},
			// lable的样式，对象形式
			labelStyle: {
				type: Object,
				default () {
					return {}
				}
			},
		},
		provide() {
			return {
				uForm: this
			};
		},
		data() {
			return {
				rules: {}
			};
		},
		created() {
			// 存储当前form下的所有u-form-item的实例
			// 不能定义在data中，否则微信小程序会造成循环引用而报错
			this.fields = [];
		},
		methods: {
			setRules(rules) {
				this.rules = rules;
			},
			// 清空所有u-form-item组件的内容，本质上是调用了u-form-item组件中的resetField()方法
			resetFields() {
				this.fields.map(field => {
					field.resetField();
				});
			},
			validateField(prop, callback) {
				return new Promise(resolve => {
					// 对所有的u-form-item进行校验
					let valid = true; // 默认通过
					this.fields.map(field => {
						// 调用每一个u-form-item实例的validation的校验方法
						if (field.prop === prop) {
							field.validation('', error => {
								// 如果任意一个u-form-item校验不通过，就意味着整个表单不通过
								if (error) {
									valid = false;
								}
								resolve(valid); // 进入promise的then方法
								// 判断是否设置了toast的提示方式，只提示最前面的表单域的第一个错误信息
								if (this.errorType.indexOf('none') === -1 && this.errorType.indexOf('toast') >= 0) {
									this.$u.toast(error);
								}
								// 调用回调方法
								if (typeof callback == 'function') callback(valid);
							});
						} else {
							callback(false)
						}
					});
				});
			},
			// 校验全部数据
			validate(callback) {
				return new Promise(resolve => {
					// 对所有的u-form-item进行校验
					let valid = true; // 默认通过
					let count = 0; // 用于标记是否检查完毕
					let errorArr = []; // 存放错误信息
					this.fields.map(field => {
						// 调用每一个u-form-item实例的validation的校验方法

						field.validation('', error => {
							// 如果任意一个u-form-item校验不通过，就意味着整个表单不通过
							if (error) {
								valid = false;
								errorArr.push(error);
							}
							// 当历遍了所有的u-form-item时，调用promise的then方法
							if (++count === this.fields.length) {
								resolve(valid); // 进入promise的then方法
								// 判断是否设置了toast的提示方式，只提示最前面的表单域的第一个错误信息
								if (this.errorType.indexOf('none') === -1 && this.errorType.indexOf('toast') >= 0 && errorArr
									.length) {
									this.$u.toast(errorArr[0]);
								}
								// 调用回调方法
								if (typeof callback == 'function') callback(valid);
							}
						});
					});
				});
			}
		}
	};
</script>

<style scoped lang="scss">
	@import "../../libs/css/style.components.scss";
</style>